/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bhatni.mockprocessor;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.jxpath.Container;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.xml.DocumentContainer;
import org.apache.velocity.app.VelocityEngine;
import org.w3c.dom.Element;

/**
 *
 * @author Viren
 */
public class MockProcessor {

    private File configFile;
    private String templatePath;
    boolean isDebug;
    private List<Scenario> scenarios = new ArrayList<Scenario>();
    VelocityEngine velocityEngine = new VelocityEngine();
    protected boolean isInit = false;

    public void init() {
        try {
            File sceneriosFile = getConfigFile();
            Container configuration = new DocumentContainer(sceneriosFile.toURL());
            JXPathContext context = JXPathContext.newContext(configuration);

            readConfiguration(context);

            Properties p = new Properties();
            p.setProperty("file.resource.loader.path", templatePath);
            velocityEngine.init(p);

        } catch (Exception ex) {
            Logger.getLogger(MockProcessor.class.getName()).log(Level.SEVERE, null, ex);
        }
        isInit = true;
    }

    private void readConfiguration(JXPathContext context) throws Exception {

        int scenarioNum = 0;
        String scenarioName;
        Iterator<Pointer> scrs = context.iteratePointers("/MockScenarios/Scenario");

        while (scrs.hasNext()) {

            JXPathContext scrContext = context.getRelativeContext(scrs.next());
            Scenario scenario = Scenario.load((Element) scrContext.selectSingleNode("."));
            if (scenario != null) {
                scenario.velocityEngine = velocityEngine;
                getScenarios().add(scenario);
            }

        }

    }

    public void process(Message in, Message out, Context context) {
        if (!isInit) {
            init();
        }

        for (Scenario scenario : scenarios) {
            if (scenario.match(in)) {
                if (isDebug) {
                    // TODO
                    Logger.getLogger(this.getClass().getName()).log(Level.INFO, "Matched scenario: " + scenario.getName() + ". Replacing macros...");
                }

                // replace macros

                scenario.applyTo(in, out);
                break;
            }
        }
    }

    /**
     * @return the configFile
     */
    public File getConfigFile() {
        return configFile;
    }

    /**
     * @param configFile the configFile to set
     */
    public void setConfigFile(File configFile) {
        this.configFile = configFile;
    }

    /**
     * @param configFile the configFile to set
     */
    public void setConfigFile(String path) {
        this.configFile = new File(path);
    }

    /**
     * @return the templatePath
     */
    public String getTemplatePath() {
        return templatePath;
    }

    /**
     * @param templatePath the templatePath to set
     */
    public void setTemplatePath(String templatePath) {
        this.templatePath = templatePath;
    }

    /**
     * @return the scenarios
     */
    public List<Scenario> getScenarios() {
        return scenarios;
    }
}
